package com.example.springboottest.example.completablefuture;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureTest {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(4);

        CompletableFuture<String> taskA = CompletableFuture.supplyAsync(() -> {
            delayRandom(100, 1000);
            System.out.println("in taskA");
            return "helloA";
        }, executor);
        CompletableFuture<Void> taskB = CompletableFuture.runAsync(() -> {
            delayRandom(2000, 3000);
            System.out.println("in taskB");
        }, executor);
        CompletableFuture<Void> taskC = CompletableFuture.runAsync(() -> {
            delayRandom(30, 100);
            System.out.println("in taskC");
//            throw new RuntimeException("task C exception");
        }, executor);
        CompletableFuture.allOf(taskA, taskB, taskC).whenComplete((result, ex) -> {
            System.out.println("whenComplete" );
            if (ex != null) {
                System.out.println(ex.getMessage());
            }
            if (!taskA.isCompletedExceptionally()) {
                System.out.println("task A isCompleted" );
            }
            if (!taskB.isCompletedExceptionally()) {
                System.out.println("task B isCompleted" );
            }
            if (!taskC.isCompletedExceptionally()) {
                System.out.println("task C isCompleted" );
            }
        });

        System.out.println("Main Thread stop");
    }

    private static Random rnd = new Random();

    static int delayRandom(int min, int max) {
        int milli = max > min ? rnd.nextInt(max - min) : 0;
        try {
            Thread.sleep(min + milli);
        } catch (InterruptedException e) {
        }
        return milli;
    }

    static Callable<Integer> externalTask = () -> {
        int time = delayRandom(20, 2000);
        return time;
    };
}
